package com.hwadee.property.controller.info;

import com.hwadee.property.pojo.Notice;
import com.hwadee.property.service.IChargeDetailService;
import com.hwadee.property.service.INoticeService;
import com.hwadee.property.service.IUserService;
import com.hwadee.property.util.AjaxResult;
import com.hwadee.property.util.FileUtil;
import com.hwadee.property.util.JwtUtil;
import com.hwadee.property.dto.PageResult;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.List;

/**
 * 通知管理控制器
 */
@RestController
@RequestMapping("/api/notice")
@Api(tags = "通知-NoticeController")
@CrossOrigin
public class NoticeController {

    @Autowired
    private INoticeService noticeService;

    @Autowired
    private IUserService userService;

    @Autowired
    private IChargeDetailService chargeDetailService;

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private FileUtil fileUtil;

    @GetMapping("/personal")
    @ApiOperation(value = "【业主】分页查询本人所属房产所在小区的物业通知", notes = "查询本人房产所属小区的所有物业通知")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "current", value = "当前页面", required = true, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "size", value = "每页大小", required = true, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "title", value = "通知标题", required = false, dataType = "String", paramType = "query")
    })
    public AjaxResult getPersonalNotice(@RequestHeader("Authorization") String token,
                                        @RequestParam(value = "current", defaultValue = "1") int current,
                                        @RequestParam(value = "size", defaultValue = "10") int size,
                                        @RequestParam(value = "title", required = false) String title) {
        // 如果token为空，返回错误
        if (token == null || token.isEmpty()) {
            return AjaxResult.fail("未授权, token 为空");
        }

        try {
            // 从token中解析出用户ID
            Long userId = jwtUtil.getUserId(token);

            // 根据用户ID查询通知
            PageResult<Notice> result = noticeService.listByOwnerId(current, size, title, userId);

            // 返回通知
            return AjaxResult.success(result);
        } catch (Exception e) {
            // token解析异常或其他异常，返回失败
            return AjaxResult.fail("查询本人通知失败");
        }
    }

    @GetMapping("/property")
    @ApiOperation(value = "【物业】分页查询通知(无内容详情)", notes = "物业分页查询本人所管辖的小区内发布的通知")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "current", value = "当前页面", required = true, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "size", value = "每页大小", required = true, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "title", value = "通知标题", required = false, dataType = "String", paramType = "query")
    })
    public AjaxResult getPropertyNotice(@RequestHeader("Authorization") String token,
                                        @RequestParam(value = "current", defaultValue = "1") int current,
                                        @RequestParam(value = "size", defaultValue = "10") int size,
                                        @RequestParam(value = "title", required = false) String title) {
        // 如果token为空，返回错误
        if (token == null || token.isEmpty()) {
            return AjaxResult.fail("未授权, token 为空");
        }

        try {
            // 从token中解析出用户ID
            Long userId = jwtUtil.getUserId(token);

            // 返回通知
            return getPage(token, current, size, userService.getById(userId).getCommunityId(), title);
        } catch (Exception e) {
            // token解析异常或其他异常，返回失败
            return AjaxResult.fail("查询通知失败"+e.getMessage());
        }
    }

    @PostMapping("/property/publish/toPay")
    @ApiOperation(value = "【物业】发布催缴费用通知", notes = "物业在所在小区内发布催缴费用的通知。缴费通知功能除请求头外无需参数，content自动生成为物业所在小区的未缴费人名单。")
    @ApiResponses({
            @ApiResponse(code = 200, message = "成功", response = Boolean.class),
            @ApiResponse(code = 400, message = "请求参数错误"),
            @ApiResponse(code = 401, message = "未授权"),
            @ApiResponse(code = 500, message = "服务器内部错误")
    })
    public AjaxResult publishNotice(@RequestHeader("Authorization") String token) {
        // 如果token为空，返回错误
        if (token == null || token.isEmpty()) {
            return AjaxResult.fail("未授权, token 为空");
        }

        try {
            // 从token中解析出用户ID
            Long userId = jwtUtil.getUserId(token);

            // 返回发布结果
            Long communityId = userService.getById(userId).getCommunityId();
            String title = "缴费提醒通知";
            StringBuilder contentBuilder = new StringBuilder("本月物业账单已发布，以下业主还未缴纳本月物业费用，请注意按时缴纳费用。\n\n");
            System.out.println("communityId = " + communityId);
            List<String> nameOfUnPayOwnerList = chargeDetailService.listUnPayOwnerName(communityId);
            for (String name : nameOfUnPayOwnerList) {
                contentBuilder.append(name).append(" ");
            }
            contentBuilder.append("\n");
            String content = contentBuilder.toString();
            String remark = "半自动化通知，内容由系统生成";
            return publishNotice(token, userId, title, content, remark, null);
        } catch (Exception e) {
            // token解析异常或其他异常，返回失败
            return AjaxResult.fail("发布通知失败" + e.getMessage());
        }
    }


    @PostMapping("/property/publish")
    @ApiOperation(value = "【物业】发布通知", notes = "发布一条新的通知")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "title", value = "通知标题", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "content", value = "通知内容", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "remark", value = "备注", required = false, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "attachment", value = "附件", required = false, dataType = "String", paramType = "query")
    })
    @ApiResponses({
            @ApiResponse(code = 200, message = "成功", response = Boolean.class),
            @ApiResponse(code = 400, message = "请求参数错误"),
            @ApiResponse(code = 401, message = "未授权"),
            @ApiResponse(code = 500, message = "服务器内部错误")
    })
    public AjaxResult publishNotice(
            @RequestHeader("Authorization") String token,
            @RequestParam String title,
            @RequestParam String content,
            @RequestParam(required = false) String remark,
            @RequestParam(required = false) MultipartFile attachment) {
        // 如果token为空，返回错误
        if (token == null || token.isEmpty()) {
            return AjaxResult.fail("未授权, token 为空");
        }

        try {
            // 从token中解析出用户ID
            Long userId = jwtUtil.getUserId(token);

            // 返回发布结果
            return publishNotice(token, userId, title, content, remark, attachment);
        } catch (Exception e) {
            // token解析异常或其他异常，返回失败
            return AjaxResult.fail("发布通知失败");
        }
    }

    /**
     * 获取通知分页列表
     * @param current 当前页码
     * @param size 每页显示条数
     * @param title 通知标题（可选）
     * @return 分页结果
     */
    @GetMapping("/page")
    @ApiOperation(value = "【管理员】获取通知分页列表(无内容详情)", notes = "根据页码、每页大小和标题查询通知分页数据。小区id不能为空。")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "current", value = "当前页码", required = true, defaultValue = "1", dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "size", value = "每页显示条数", required = true, defaultValue = "10", dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "communityId", value = "小区ID", required = false, dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "title", value = "通知标题（可选）", required = false, dataType = "String", paramType = "query")
    })
    public AjaxResult getPage(@RequestHeader("Authorization") String token,
            @RequestParam(value = "current", defaultValue = "1") int current,
            @RequestParam(value = "size", defaultValue = "10") int size,
            @RequestParam(value = "communityId", required = false) Long communityId,
            @RequestParam(value = "title", required = false) String title) {

        // 执行分页查询
        PageResult<Notice> result = noticeService.getPage(current, size, communityId, title);
        return AjaxResult.success(result);
    }

    /**
     * 根据物业ID查询通知列表
     * @param propertyStaffId 物业ID
     * @return 通知列表
     */
    @GetMapping("/list")
    @ApiOperation(value = "【管理员】根据物业ID查询通知列表", notes = "根据物业ID查询所有通知")
    @ApiResponses({
            @ApiResponse(code = 200, message = "成功", response = Notice.class, responseContainer = "List")
    })
    public AjaxResult listNotices(@RequestHeader("Authorization") String token, @RequestParam Long propertyStaffId) {
        List<Notice> notices = noticeService.listByPropertyStaffId(propertyStaffId);
        return AjaxResult.success(notices);
    }

    /**
     * 发布通知
     * 注意：物业人员必须具有相应的权限才能发布通知。
     *
     * @param propertyStaffID 物业人员 ID
     * @param title           通知标题
     * @param content         通知内容
     * @param remark          备注（可选）
     * @param attachment      附件（可选）
     * @return 发布结果：返回一个布尔值，表示通知是否发布成功
     */
    @PostMapping("/publish/{propertyStaffID}")
    @ApiOperation(value = "【管理员】发布通知", notes = "发布一条新的通知")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "propertyStaffID", value = "物业人员 ID", required = true, dataType = "Long", paramType = "path"),
            @ApiImplicitParam(name = "title", value = "通知标题", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "content", value = "通知内容", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "remark", value = "备注", required = false, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "attachment", value = "附件", required = false, dataType = "MultipartFile", paramType = "query")
    })
    @ApiResponses({
            @ApiResponse(code = 200, message = "成功", response = Boolean.class),
            @ApiResponse(code = 400, message = "请求参数错误"),
            @ApiResponse(code = 401, message = "未授权"),
            @ApiResponse(code = 500, message = "服务器内部错误")
    })
    public AjaxResult publishNotice(@RequestHeader("Authorization") String token,
            @PathVariable Long propertyStaffID,
            @RequestParam String title,
            @RequestParam String content,
            @RequestParam(required = false) String remark,
            @RequestParam(required = false) MultipartFile attachment) {
        Notice notice = new Notice();
        notice.setPropertyStaffId(propertyStaffID);
        notice.setTitle(title);
        notice.setContent(content);
        notice.setRemark(remark);
        if (attachment != null) {
            String attachmentPath = fileUtil.uploadFileAndGetPath(attachment, "notice");
            notice.setAttachment(attachmentPath);
        }
        boolean result = noticeService.publishNotice(notice);
        return result ? AjaxResult.success(result) : AjaxResult.fail("发布失败");
    }

    /**
     * 更新通知
     * @param noticeID 通知 ID
     * @param title 通知标题
     * @param content 通知内容
     * @param remark 备注
     * @param attachment 附件
     * @return 更新结果
     */
    @PutMapping("/update/{noticeID}")
    @ApiOperation(value = "【管理员】更新通知", notes = "更新一条已存在的通知")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "noticeID", value = "通知 ID", required = true, dataType = "long", paramType = "path"),
            @ApiImplicitParam(name = "title", value = "通知标题", required = false, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "content", value = "通知内容", required = false, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "remark", value = "备注", required = false, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "attachment", value = "附件", required = false, dataType = "string", paramType = "query")
    })
    @ApiResponses({
            @ApiResponse(code = 200, message = "成功", response = Boolean.class)
    })
    public AjaxResult updateNotice(@RequestHeader("Authorization") String token,
            @PathVariable Long noticeID,
            @RequestParam(value = "title", required = false) String title,
            @RequestParam(value = "content", required = false) String content,
            @RequestParam(value = "remark", required = false) String remark,
            @RequestParam(value = "attachment", required = false) MultipartFile attachment) {
        boolean result = noticeService.updateNotice(noticeID, title, content, remark, attachment);
        return result ? AjaxResult.success(result) : AjaxResult.fail("更新失败");
    }

    /**
     * 删除通知
     * @param id 通知ID
     * @return 删除结果
     */
    @DeleteMapping("/delete/{id}")
    @ApiOperation(value = "【管理员】删除通知", notes = "根据通知ID删除通知")
    @ApiResponses({
            @ApiResponse(code = 200, message = "成功", response = Boolean.class)
    })
    public AjaxResult deleteNotice(@RequestHeader("Authorization") String token, @PathVariable Long id) {
        boolean result = noticeService.deleteNotice(id);
        return result ? AjaxResult.success(result) : AjaxResult.fail("删除失败");
    }

    /**
     * 根据ID查询通知详情
     * @param id 通知ID
     * @return 通知详情
     */
    @GetMapping("/all/{id}")
    @ApiOperation(value = "【所有人】根据ID查询通知详情", notes = "根据通知ID查询通知详情")
    @ApiResponses({
            @ApiResponse(code = 200, message = "成功", response = Notice.class),
            @ApiResponse(code = 404, message = "通知不存在", response = String.class)
    })
    public AjaxResult getNoticeById(@RequestHeader("Authorization") String token, @PathVariable Long id) {
        Notice notice = noticeService.getById(id);
        List<Notice> notices = new ArrayList<>();
        notices.add(notice);
        if (notice == null) {
            return AjaxResult.error(404, "通知不存在");
        }
        return AjaxResult.success(notices);
    }
}
